import { h, Time, Schema } from "koishi"

export const name = "npm-watcher"
export const inject = ["database"]

export const Config = Schema.object({
  query: String,
  interval: Schema.number().default(5 * Time.minute),
  channels: Schema.array(String), // platform:channelId
  npmRegistry: Schema.string().default("https://registry.npmjs.org").role("url"),
})

/** @param {import("koishi").Context} ctx */
export function apply(ctx, config) {
  let lastPoll = -Infinity
  const lastVersions = {}

  async function fetchPackages(query) {
    const res = await ctx.http.get(
      `${config.npmRegistry}/-/v1/search?text=${query}&size=250`
    )
    return res.objects.map(obj => obj.package.name)
  }

  async function checkPackages() {
    const now = Date.now()
    let packages = []
    try {
      packages = await fetchPackages(config.query)
    } catch (e) {
      ctx.logger.warn("Failed to fetch package list:", e)
      return
    }
    ctx.logger.debug(packages)
    for (const pkg of packages) {
      try {
        const data = await ctx.http.get(`${config.npmRegistry}/${pkg}`)
        const latest = data["dist-tags"]?.latest
        if (!latest) continue
        const latestTime = Date.parse(data.time[latest])
        if (
          lastVersions[pkg] &&
          lastVersions[pkg] !== latest &&
          (
            !data.time[lastVersions[pkg]] ||
            latestTime > lastPoll ||
            latestTime > Date.parse(data.time[lastVersions[pkg]])
          )
        ) {
          // New version published (and not just unpublishing or tag change)
          const info = data.versions[latest]
          ctx.broadcast(config.channels, h("i18n:object", {
            path: "lnnbot.npm-watcher.publish",
            data: { name: pkg, version: latest, author: info._npmUser?.name },
          }))
        }
        lastVersions[pkg] = latest
      } catch (e) {
        ctx.logger.warn(e)
      }
    }

    lastPoll = now
  }

  ctx.setInterval(checkPackages, config.interval)
  checkPackages()

  ctx.i18n.define("zh-CN", "lnnbot.npm-watcher", {
    publish: "{author} 发布了 npm 包 {name} 的版本 {version}。",
  })
}
